package org.wuxinshui.boosters.interview02;

import java.util.concurrent.*;

/**
 * 演示CallerRunsPolicy拒绝策略的使用场景
 * 场景：模拟短时间内提交大量任务，线程池与队列满时，被拒绝的任务由提交任务的线程（主线程）执行
 */
public class ThreadPoolCallerRunsPolicyDemo {
    // 自定义任务类，封装任务ID，避免共享变量问题
    static class Task implements Runnable {
        private final int taskId; // 任务ID（不可变，确保线程安全）

        public Task(int taskId) {
            this.taskId = taskId;
        }

        @Override
        public void run() {
            try {
                // 模拟任务执行耗时（1秒）
                Thread.sleep(1000);
                // 打印执行信息：任务ID+执行线程名
                System.out.printf("【任务%d】执行完成，执行线程：%s%n",
                        taskId, Thread.currentThread().getName());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt(); // 恢复中断状态
                System.out.printf("【任务%d】被中断%n", taskId);
            }
        }
    }

    public static void main(String[] args) {
        // 1. 配置线程池参数（小容量设计，便于触发拒绝策略）
        ThreadPoolExecutor executor = getThreadPoolExecutor();

        // 3. 提交10个任务（线程池最大承载量=4+3=7，第8个及以后触发拒绝策略）
        System.out.println("开始提交任务...");
        for (int i = 1; i <= 10; i++) {
            // 每个任务创建独立实例，通过构造方法传入ID（避免共享变量问题）
            Task task = new Task(i);
            System.out.printf("提交任务%d%n", i);
            executor.execute(task);
        }

        // 4. 优雅关闭线程池
        executor.shutdown();
        try {
            // 等待所有任务完成（最多等待15秒）
            if (!executor.awaitTermination(15, TimeUnit.SECONDS)) {
                // 超时未完成则强制关闭
                executor.shutdownNow();
                System.out.println("线程池强制关闭");
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        System.out.println("所有任务处理结束");
    }

    private static ThreadPoolExecutor getThreadPoolExecutor() {
        int corePoolSize = 2;
        int maximumPoolSize = 4;
        long keepAliveTime = 30;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(3); // 队列容量3

        // 线程工厂：自定义线程名，便于日志追踪
        ThreadFactory threadFactory = new ThreadFactory() {
            private int threadCount = 0;

            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r, "worker-thread-" + (++threadCount));
                thread.setDaemon(false); // 非守护线程，确保任务完成
                return thread;
            }
        };

        // 拒绝策略：使用CallerRunsPolicy
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();

        // 2. 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
        return executor;
    }


}
